package com.lapelife.backend.service.impl;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lapelife.backend.common.ErrorCode;
import com.lapelife.backend.common.RedisContains;
import com.lapelife.backend.common.ResponseResult;
import com.lapelife.backend.model.domain.LoginUser;
import com.lapelife.backend.model.domain.SysUser;
import com.lapelife.backend.model.request.UserRequest;
import com.lapelife.backend.service.SysUserService;
import com.lapelife.backend.mapper.SysUserMapper;
import com.lapelife.backend.utils.EmailUtil;
import com.lapelife.backend.utils.RedisUtil;
import com.lapelife.backend.utils.ValidateCodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.Objects;

/**
* @author Mir.Lliao
* @description 针对表【sys_user(用户信息表)】的数据库操作Service实现
* @createDate 2023-04-23 20:08:21
*/
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser>
    implements SysUserService{

    private SysUserMapper sysUserMapper;

    private RedisUtil redisUtil;

    @Autowired
    public void setRedisUtil(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }

    @Autowired
    public void setSysUserMapper(SysUserMapper sysUserMapper) {
        this.sysUserMapper = sysUserMapper;
    }

    @Override
    public ResponseResult<SysUser> info() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        SysUser sysUser = loginUser.getSysUser();
        sysUser.setPassword("");
        return ResponseResult.suc(sysUser);
    }

    @Override
    public ResponseResult<String> updateUserInfo(UserRequest user) {
        // 验证用户名是否存在
        SysUser sysUser = sysUserMapper.selectOneByUserName(user.getUserName());
        if (!Objects.isNull(sysUser)) {
            return ResponseResult.fail(5500, "用户名已被使用");
        }
        // 获取用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        // 将请求用户参数的空值转为null
        user.patternEmpty();
        // 将需要修改的值赋值给数据库实体
        sysUser = Convert.convert(SysUser.class, user);
        sysUser.setUserId(loginUser.getSysUser().getUserId());
        // 修改
        int result = sysUserMapper.updateById(sysUser);
        // 修改完后存入redis
        if (result > 0) {
            loginUser.setSysUser(getById(sysUser.getUserId()));
            redisUtil.set(RedisContains.USER_LOGIN + sysUser.getUserId(), JSON.toJSON(loginUser));
        }else if (result == 0) {
            return ResponseResult.fail(ErrorCode.PARAMS_ERROR);
        }
        return ResponseResult.suc("用户信息修改成功");
    }

    @Override
    public ResponseResult<String> updatePassword(UserRequest user) {
        String pass = user.getPassword();
        String newPass = user.getNewPass();

        if (!StringUtils.hasText(pass) || !StringUtils.hasText(newPass)) {
            return ResponseResult.fail(ErrorCode.PARAMS_ERROR);
        }

        // 密码加密
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String newPassEncode = passwordEncoder.encode(newPass);

        // 获取用户id
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        SysUser u = getById(loginUser.getSysUser().getUserId());
        if (!passwordEncoder.matches(pass,u.getPassword())) {
            return ResponseResult.fail(ErrorCode.RESULT_ERROR.getCode(),"原密码错误");
        }

        // 创建新对象，并赋值
        SysUser sysUser = new SysUser();
        sysUser.setUserId(u.getUserId());
        sysUser.setPassword(newPassEncode);
        sysUser.setUpdateBy(StringUtils.hasText(user.getUpdateBy())? user.getUpdateBy() : null);

        // 修改
        int result = sysUserMapper.updateById(sysUser);
        if (result == 0) {
            return ResponseResult.fail(ErrorCode.PARAMS_ERROR);
        }

        return ResponseResult.suc("密码修改成功");
    }

    @Override
    public ResponseResult<String> sendCode(String email) {
        if (!StringUtils.hasText(email)) {
            return ResponseResult.fail(ErrorCode.PARAMS_ERROR);
        }
        // 创建验证码
        String code = ValidateCodeUtils.generateValidateCode4String(5);
        // 发送验证码
        EmailUtil.sendAuthCodeEmail(email, code);
        // 将验证码和邮箱保存到redis中，并设置过期时间
        redisUtil.set(RedisContains.USER_PASSWORD_EMAIL_CODE + email, code, 60);
        return ResponseResult.suc("验证码发送成功！");
    }

    @Override
    public ResponseResult<String> updatePasswordByCode(UserRequest user) {

        String email = user.getEmail();
        String pass = user.getPassword();
        String oldCode = user.getCode();

        if (!StringUtils.hasText(pass) || !StringUtils.hasText(email) || !StringUtils.hasText(oldCode)) {
            return ResponseResult.fail(ErrorCode.PARAMS_ERROR);
        }
        // 验证验证码
        Object code = redisUtil.get(RedisContains.USER_PASSWORD_EMAIL_CODE + email);
        if(code == null){
            return ResponseResult.suc("验证码已过期，请重新发送");
        }
        if (!code.toString().equalsIgnoreCase(oldCode)) {
            return ResponseResult.suc("验证码错误");
        }

        // 密码加密
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String encode = passwordEncoder.encode(pass);

        // 设置匹配邮箱，修改对象，并进行赋值
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getEmail, email).eq(SysUser::getStatus, "0");
        SysUser sysUser = new SysUser();
        sysUser.setPassword(encode);
        sysUser.setUpdateBy(StringUtils.hasText(user.getUpdateBy())? user.getUpdateBy() : null);

        // 修改
        int result = sysUserMapper.update(sysUser,wrapper);
        if (result == 0) {
            return ResponseResult.fail(ErrorCode.PARAMS_ERROR);
        }

        return ResponseResult.suc("密码修改成功");
    }
}




